package com.tvunetworks.center.device.service.impl;

import com.tvunetworks.center.common.model.param.search.SlugInfo;
import com.tvunetworks.center.common.util.JsonUtil;
import com.tvunetworks.center.common.util.MyUtil;
import com.tvunetworks.center.device.constant.DeviceApiConstant;
import com.tvunetworks.center.device.mapper.GridMetadataMapper;
import com.tvunetworks.center.device.model.GridMetadata;
import com.tvunetworks.center.device.model.MyDevice;
import com.tvunetworks.center.device.service.DeviceService;
import com.tvunetworks.center.device.service.GridMetadataService;
import com.tvunetworks.center.device.service.feign.TvuSearchFeignService;
import com.tvunetworks.center.device.util.ThreadPoolUtil;
import com.tvunetworks.center.gs.model.Device;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.toList;

/**
 * @program: tvucc-aggregator
 * @description: GridMetadataService实现
 * @author Kevin_Li
 * @create: 2020-01-08 12:06
 **/
@Slf4j
@Service
public class GridMetadataServiceImpl implements GridMetadataService {

    @Autowired
    private GridMetadataMapper gridMetadataMapper;
    @Autowired
    private DeviceService deviceService;
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private TvuSearchFeignService tvuSearchFeignService;

    @Value("${search.url}")
    private String searchUrl;
    @Value("${reportSlugToSearch}")
    private String reportSlugToSearch;


    @Override
    public GridMetadata getGridMetadataByPeerId(String peerId) {
        GridMetadata record = new GridMetadata();
        record.setPeerId(peerId);
        record.setDeleteFlag(DeviceApiConstant.FLAG_FALSE);
        return gridMetadataMapper.selectOne(record);
    }

    @Override
    public int updateGridMetadata(GridMetadata gridMetadata) {
        StringBuffer metaData = new StringBuffer();
        if (StringUtils.isNotBlank(gridMetadata.getStorySlug())) {
            metaData.append(gridMetadata.getStorySlug());
        }
        if (StringUtils.isNotBlank(gridMetadata.getExtraneousInfo())) {
            metaData.append("\n" + gridMetadata.getExtraneousInfo());
        }
        GridMetadata metadata = this.getGridMetadataByPeerId(gridMetadata.getPeerId());
        MyDevice device = deviceService.getDBDevice(gridMetadata.getPeerId());

        // 格式化经纬度，保留小数点后5位
        String latitude = gridMetadata.getLatitude();
        String longitude = gridMetadata.getLongitude();
        if (StringUtils.isNotEmpty(latitude)) {
            latitude = formatLatLong(latitude);
            gridMetadata.setLatitude(latitude);
        }
        if (StringUtils.isNotEmpty(longitude)) {
            longitude = formatLatLong(longitude);
            gridMetadata.setLongitude(longitude);
        }

        if (metadata == null) {
            if (metaData != null) {
                device.setMetaData(metaData.toString());
                gridMetadata.setStorySlug(metaData.toString());
                deviceService.updateDevice(device);
            }
            this.addGridMetadata(gridMetadata);
        } else {
            //update metadata
            gridMetadata.setId(metadata.getId());
            gridMetadata.setExpireFlag(DeviceApiConstant.FLAG_FALSE);
            if (metaData != null) {
                device.setMetaData(metaData.toString());
                gridMetadata.setStorySlug(metaData.toString());
                deviceService.updateDevice(device);
            }
            gridMetadataMapper.updateByPrimaryKeySelective(gridMetadata);
        }
        //需要将slug信息推送到search服务
        ThreadPoolUtil.SERVICETHREADPOOL.execute(new Runnable() {
            @Override
            public void run() {
                sendMediaMind(metaData.toString(), device.getPeerId(), gridMetadata.getCreateTime());
            }
        });
        return 0;
    }

    @Override
    public void addGridMetadata(GridMetadata gridMetadata) {
        gridMetadata.setId(MyUtil.getUUID());
        gridMetadata.setExpireFlag(DeviceApiConstant.FLAG_FALSE);
        gridMetadata.setDeleteFlag(DeviceApiConstant.FLAG_FALSE);
        gridMetadataMapper.insert(gridMetadata);
    }

    @Override
    public String synGridSlug() throws Exception {
        //获取search中所有grid最新的slug
        List<SlugInfo> searchSlugList = tvuSearchFeignService.newestSlugInfo(new ArrayList<>());
        int synNum = gridMetadataMapper.synGridSlug(searchSlugList);
        int synDeviceNum = deviceService.synGridSlug(searchSlugList);
        //search表中有的grid,但是在tvu_grid_metadata没有这个grid Id 需要新增一条进去
        List<String> gridAllPeerIds = gridMetadataMapper.allGridIds();
        List<String> searchAllPeerIds = searchSlugList.stream().map(SlugInfo::getPeerId).collect(toList());
        List<String> reducePeerId = searchAllPeerIds.stream().filter(item -> !gridAllPeerIds.contains(item.toLowerCase()) && !gridAllPeerIds.contains(item.toUpperCase())).collect(toList());
        String result = "grid:" + synNum + "  device:" + synDeviceNum;
        if (reducePeerId == null || reducePeerId.size() == 0) {
            return result;
        }
        List<String> gridIds = new ArrayList<>();
        for (String peerId : reducePeerId) {
            Device currentDevice = deviceService.getCurrentDevice(peerId);
            if (currentDevice == null || !currentDevice.getType().equals("X")) {
                continue;
            }
            gridIds.add(peerId);
        }
        if (gridIds.size() == 0) {
            return result;
        }
        List<SlugInfo> reduceSlugInfos = tvuSearchFeignService.newestSlugInfo(gridIds);
        Map<String, String> slugMap = reduceSlugInfos.stream().collect(Collectors.toMap(SlugInfo::getPeerId, SlugInfo::getSlug));
        //只关注grid
        for (String gridId : gridIds) {
            GridMetadata gridMetadata = new GridMetadata();
            gridMetadata.setPeerId(gridId);
            gridMetadata.setDeleteFlag(0);
            List<GridMetadata> metadataList = gridMetadataMapper.select(gridMetadata);
            if (!CollectionUtils.isEmpty(metadataList)) {
                continue;
            }
            long currentTimeMillis = System.currentTimeMillis();
            gridMetadata.setStorySlug(slugMap.get(gridId));
            gridMetadata.setId(MyUtil.getUUID());
            gridMetadata.setCreateTime(currentTimeMillis);
            gridMetadata.setUpdateTime(currentTimeMillis);
            gridMetadataMapper.insert(gridMetadata);
            log.error("tvu_grid_metadata inset new data:{}:", gridMetadata);
        }
        return result;
    }

    @Override
    public boolean notificationDeleteSlug(SlugInfo slugInfo) throws Exception {
        log.error("[notificationDeleteSlug] info:{}", slugInfo);
        //查出这个grid最新的slug
        List<String> peerIds = new ArrayList<>(1);
        String peerId = slugInfo.getPeerId();
        if (StringUtils.isBlank(peerId)){
            return false;
        }
        peerIds.add(peerId);
        List<SlugInfo> searchSlugList = tvuSearchFeignService.newestSlugInfo(peerIds);
        //2.如果不存在slug,将slug更改为空
        if (CollectionUtils.isEmpty(searchSlugList)){
            log.error("[notificationDeleteSlug] peerId:{} no newest slug, empty slug ...", peerId);
           gridMetadataMapper.updateGridSlug(peerId, "");
           deviceService.updateMetadata(peerId, "");
           return true;
        }
        //3.如果最后一条slug结束时间小于当前时间,将slug更改为空
         //同步任务会做这件事,这里不用处理
        return false;
    }

    /**
     *
     * @param metaData metaData
     * @param peerId  peerId
     * @param startTime startTime
     */
   void sendMediaMind(String metaData, String peerId, Long startTime){
       String url = "";
       String pm = "";
       try {
           Map<String, Object> params = new HashMap<>();
           params.put("peerId", peerId);
           params.put("gridLinkMetadata", metaData);
           if (startTime != null){

               params.put("updateTime", startTime);
           }
           pm = JsonUtil.toJsonStr(params);
           url = searchUrl + reportSlugToSearch;
           HttpHeaders requestHeaders = new HttpHeaders();
           requestHeaders.setContentType(MediaType.APPLICATION_JSON);
           HttpEntity<String> requestEntity = new HttpEntity<String>(pm, requestHeaders);
           log.error("[updateGridMetadata] send search synMetadata URL:{}, param:{}", url, params);
           String body = restTemplate.postForEntity(url, requestEntity, String.class).getBody();
           log.error("[updateGridMetadata] send search synMetadata  body:{}", body);
       }catch (Exception e) {
           log.error(e.toString(),e);
       }
   }

    /**
     *
     * @param string string
     * @return String
     */
    public String formatLatLong(String string){
        Double dou = Double.valueOf(string.trim());
        return String.format("%.5f", dou);
    }
}
